home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / compress / gnucpio.zip / RMT.C < prev    next >
C/C++ Source or Header  |  1995-12-20  |  6KB  |  292 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. char copyright[] =
  20. "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  21.  All rights reserved.\n";
  22. #endif /* not lint */
  23.  
  24. /*
  25.  * rmt
  26.  */
  27. #include <stdio.h>
  28. #ifndef __linux
  29. /* Kludge alert:  We should really fix this by having configure figure
  30.    out if we need sgtty.h or not, so it can define HAVE_SGGTY_H and
  31.    also add rmt to the build targets.  For now we'll just add this
  32.    ifndef so make rmt will work on Linux.  */
  33. #include <sgtty.h>
  34. #endif
  35. #include <sys/types.h>
  36. #include <sys/socket.h>
  37. #ifdef HAVE_SYS_GENTAPE_H    /* e.g., ISC UNIX */
  38. #include <sys/gentape.h>
  39. #else
  40. #ifdef M_UNIX
  41. #include <sys/tape.h>
  42. #else
  43. #include <sys/mtio.h>
  44. #endif
  45. #endif
  46. #include <errno.h>
  47.  
  48. #if defined (_I386) && defined (_AIX)
  49. #include <fcntl.h>
  50. #endif
  51.  
  52. #ifdef HAVE_UNISTD_H
  53. #include <unistd.h>
  54. #else
  55. long lseek ();
  56. #endif
  57.  
  58. #ifdef STDC_HEADERS
  59. #include <string.h>
  60. #include <stdlib.h>
  61. #else
  62. extern char *malloc ();
  63. #endif
  64.  
  65. int tape = -1;
  66.  
  67. char *record;
  68. int maxrecsize = -1;
  69. char *checkbuf ();
  70. void getstring ();
  71. void error ();
  72.  
  73. #define    SSIZE    64
  74. char device[SSIZE];
  75. char count[SSIZE], mode[SSIZE], pos[SSIZE], op[SSIZE];
  76.  
  77. extern errno;
  78. extern char *sys_errlist[];
  79. char resp[BUFSIZ];
  80.  
  81. FILE *debug;
  82. #define    DEBUG(f)    if (debug) fprintf(debug, f)
  83. #define    DEBUG1(f,a)    if (debug) fprintf(debug, f, a)
  84. #define    DEBUG2(f,a1,a2)    if (debug) fprintf(debug, f, a1, a2)
  85.  
  86. int
  87. main (argc, argv)
  88.      int argc;
  89.      char **argv;
  90. {
  91.   int rval;
  92.   char c;
  93.   int n, i, cc;
  94.  
  95.   argc--, argv++;
  96.   if (argc > 0)
  97.     {
  98.       debug = fopen (*argv, "w");
  99.       if (debug == 0)
  100.     exit (1);
  101.       (void) setbuf (debug, (char *) 0);
  102.     }
  103. top:
  104.   errno = 0;
  105.   rval = 0;
  106.   if (read (0, &c, 1) != 1)
  107.     exit (0);
  108.   switch (c)
  109.     {
  110.  
  111.     case 'O':
  112.       if (tape >= 0)
  113.     (void) close (tape);
  114.       getstring (device);
  115.       getstring (mode);
  116.       DEBUG2 ("rmtd: O %s %s\n", device, mode);
  117. #if defined (i386) && defined (AIX)
  118.       /* This is alleged to fix a byte ordering problem. */
  119.       /* I'm quite suspicious if it's right. -- mib */
  120.       {
  121.     int oflag = atoi (mode);
  122.     int nflag = 0;
  123.     if ((oflag & 3) == 0)
  124.       nflag |= O_RDONLY;
  125.     if (oflag & 1)
  126.       nflag |= O_WRONLY;
  127.     if (oflag & 2)
  128.       nflag |= O_RDWR;
  129.     if (oflag & 0x0008)
  130.       nflag |= O_APPEND;
  131.     if (oflag & 0x0200)
  132.       nflag |= O_CREAT;
  133.     if (oflag & 0x0400)
  134.       nflag |= O_TRUNC;
  135.     if (oflag & 0x0800)
  136.       nflag |= O_EXCL;
  137.     tape = open (device, nflag, 0666);
  138.       }
  139. #else
  140.       tape = open (device, atoi (mode), 0666);
  141. #endif
  142.       if (tape < 0)
  143.     goto ioerror;
  144.       goto respond;
  145.  
  146.     case 'C':
  147.       DEBUG ("rmtd: C\n");
  148.       getstring (device);    /* discard */
  149.       if (close (tape) < 0)
  150.     goto ioerror;
  151.       tape = -1;
  152.       goto respond;
  153.  
  154.     case 'L':
  155.       getstring (count);
  156.       getstring (pos);
  157.       DEBUG2 ("rmtd: L %s %s\n", count, pos);
  158.       rval = lseek (tape, (long) atoi (count), atoi (pos));
  159.       if (rval < 0)
  160.     goto ioerror;
  161.       goto respond;
  162.  
  163.     case 'W':
  164.       getstring (count);
  165.       n = atoi (count);
  166.       DEBUG1 ("rmtd: W %s\n", count);
  167.       record = checkbuf (record, n);
  168.       for (i = 0; i < n; i += cc)
  169.     {
  170.       cc = read (0, &record[i], n - i);
  171.       if (cc <= 0)
  172.         {
  173.           DEBUG ("rmtd: premature eof\n");
  174.           exit (2);
  175.         }
  176.     }
  177.       rval = write (tape, record, n);
  178.       if (rval < 0)
  179.     goto ioerror;
  180.       goto respond;
  181.  
  182.     case 'R':
  183.       getstring (count);
  184.       DEBUG1 ("rmtd: R %s\n", count);
  185.       n = atoi (count);
  186.       record = checkbuf (record, n);
  187.       rval = read (tape, record, n);
  188.       if (rval < 0)
  189.     goto ioerror;
  190.       (void) sprintf (resp, "A%d\n", rval);
  191.       (void) write (1, resp, strlen (resp));
  192.       (void) write (1, record, rval);
  193.       goto top;
  194.  
  195.     case 'I':
  196.       getstring (op);
  197.       getstring (count);
  198.       DEBUG2 ("rmtd: I %s %s\n", op, count);
  199. #ifdef MTIOCTOP
  200.       {
  201.     struct mtop mtop;
  202.     mtop.mt_op = atoi (op);
  203.     mtop.mt_count = atoi (count);
  204.     if (ioctl (tape, MTIOCTOP, (char *) &mtop) < 0)
  205.       goto ioerror;
  206.     rval = mtop.mt_count;
  207.       }
  208. #endif
  209.       goto respond;
  210.  
  211.     case 'S':            /* status */
  212.       DEBUG ("rmtd: S\n");
  213.       {
  214. #ifdef MTIOCGET
  215.     struct mtget mtget;
  216.     if (ioctl (tape, MTIOCGET, (char *) &mtget) < 0)
  217.       goto ioerror;
  218.     rval = sizeof (mtget);
  219.     (void) sprintf (resp, "A%d\n", rval);
  220.     (void) write (1, resp, strlen (resp));
  221.     (void) write (1, (char *) &mtget, sizeof (mtget));
  222. #endif
  223.     goto top;
  224.       }
  225.  
  226.     default:
  227.       DEBUG1 ("rmtd: garbage command %c\n", c);
  228.       exit (3);
  229.     }
  230. respond:
  231.   DEBUG1 ("rmtd: A %d\n", rval);
  232.   (void) sprintf (resp, "A%d\n", rval);
  233.   (void) write (1, resp, strlen (resp));
  234.   goto top;
  235. ioerror:
  236.   error (errno);
  237.   goto top;
  238. }
  239.  
  240. void
  241. getstring (bp)
  242.      char *bp;
  243. {
  244.   int i;
  245.   char *cp = bp;
  246.  
  247.   for (i = 0; i < SSIZE; i++)
  248.     {
  249.       if (read (0, cp + i, 1) != 1)
  250.     exit (0);
  251.       if (cp[i] == '\n')
  252.     break;
  253.     }
  254.   cp[i] = '\0';
  255. }
  256.  
  257. char *
  258. checkbuf (record, size)
  259.      char *record;
  260.      int size;
  261. {
  262.   if (size <= maxrecsize)
  263.     return (record);
  264.   if (record != 0)
  265.     free (record);
  266.   record = malloc (size);
  267.   if (record == 0)
  268.     {
  269.       DEBUG ("rmtd: cannot allocate buffer space\n");
  270.       exit (4);
  271.     }
  272.   maxrecsize = size;
  273. #ifdef SO_RCVBUF
  274.   while (size > 1024 &&
  275.    setsockopt (0, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof (size)) < 0)
  276.     size -= 1024;
  277. #else
  278.   size = 1 + ((size - 1) % 1024);
  279. #endif
  280.   return (record);
  281. }
  282.  
  283. void
  284. error (num)
  285.      int num;
  286. {
  287.  
  288.   DEBUG2 ("rmtd: E %d (%s)\n", num, sys_errlist[num]);
  289.   (void) sprintf (resp, "E%d\n%s\n", num, sys_errlist[num]);
  290.   (void) write (1, resp, strlen (resp));
  291. }
  292.